package org.gridlab.gridsphere.services.visualization;
import org.jfree.chart.*;
import org.jfree.data.general.*;
import org.jfree.util.TableOrder;
import org.jfree.data.category.CategoryDataset;
import org.jfree.chart.plot.*;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.util.Rotation;
import javax.portlet.*;
import java.util.Map;
import java.util.HashMap;


/**
 * Klasa abstrakcyjna do generowania wykresów kołowych i słupkowych
 * @author Krzysztof Goj
 */
public abstract class StatisticalChartGenerator extends ImageChartGenerator {
    /**
     * Tworzy nowy obiekt typu BarChartGenerator
     * @param dp DataProvider z danymi dla tego typu wykresu
     * @param c Kontekst portletu
     */
    public StatisticalChartGenerator(DataProvider dp, PortletContext c) {
        super(dp, c);
    }

    /**
     * Zwraca typ danych wymagany przez ten ChartGenerator
     * @return Typ danych wymagany przez ten ChartGenerator, czyli NamedNumber[].class
     */
    protected Class dataType() {
        return NamedNumber[].class;
    }

    /**
     * Wywołuje JFreeChart w celu wygenerowania wykresu
     * @param dataset Dane, z których ma być wygenerowany wykres
     */
    abstract void finalTouchWithJFCStuff(CategoryDataset dataset);

    /**
     * Przygotowuje dane dla JFreeChart na podstawie danych DataProvidera
     * @throws org.gridlab.gridsphere.services.visualization.ChartGeneratorException 
     */
    protected void doJFreeChartStuff() throws ChartGeneratorException {
        NamedNumber[] nnArr = (NamedNumber[]) dataProvider.getData(0);
        Map labelToRowMap = new HashMap();
        int seriesLen = nnArr.length;

        String[] seriesNames = new String[dataProvider.getSeriesCount()];
        String[] labels = new String[seriesLen];
        double[][] data = new double[seriesNames.length][labels.length];

        for(int i=0; i<seriesLen; ++i) {
            labelToRowMap.put(nnArr[i].getLabel(), new Integer(i));
            labels[i] = nnArr[i].getLabel();
        }

        for(int i=0; i<dataProvider.getSeriesCount(); ++i) {
            nnArr = (NamedNumber[]) dataProvider.getData(i);
            seriesNames[i] = dataProvider.getSeriesName(i);
            for(int j=0; j<seriesLen; ++j) {
                NamedNumber nn = nnArr[j];
                Integer ii = (Integer) labelToRowMap.get(nn.getLabel());
                if(ii == null)
                    throw new ChartGeneratorException("Bad label: " + nn.getLabel());
                data[i][ii.intValue()] = nn.getValue().doubleValue();
            }
        }

        CategoryDataset dataset = DatasetUtilities.createCategoryDataset(seriesNames, labels, data);
        finalTouchWithJFCStuff(dataset);
    }
}


